﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ExtensionMethods.cs" company="GT">
//   Gunther Taborga
// </copyright>
// <summary>
//   Defines the ExtensionMethods type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace BatchID3.Extensions
{
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Linq;
    using System.Reflection;

    using BatchID3.Enumerations;
    using BatchID3.Mp3;

    public static class ExtensionMethods
    {
        public static List<PropertyInfo> GetPublicProperties(this Type type)
        {
            if (type.IsInterface)
            {
                var propertyInfos = new List<PropertyInfo>();

                var considered = new List<Type>();
                var queue = new Queue<Type>();
                
                considered.Add(type);
                queue.Enqueue(type);

                while (queue.Count > 0)
                {
                    var subType = queue.Dequeue();
                    foreach (var subInterface in subType.GetInterfaces().Where(subInterface => !considered.Contains(subInterface)))
                    {
                        considered.Add(subInterface);
                        queue.Enqueue(subInterface);
                    }

                    var typeProperties = subType.GetProperties(
                        BindingFlags.FlattenHierarchy
                        | BindingFlags.Public
                        | BindingFlags.Instance);

                    var newPropertyInfos = typeProperties.Where(x => !propertyInfos.Contains(x));

                    propertyInfos.InsertRange(0, newPropertyInfos);
                }

                return propertyInfos;
            }

            return type.GetProperties(BindingFlags.FlattenHierarchy
                                      | BindingFlags.Public | BindingFlags.Instance).ToList();
        }

        public static string GetTagAttributeFromToken(this IMp3Entity mp3, TagToken tagToken)
        {
            var tagAttribute = string.Empty;
            switch (tagToken)
            {
                case TagToken.Artist:
                    tagAttribute = mp3.Artist;
                    break;
                case TagToken.Album:
                    tagAttribute = mp3.Album;
                    break;
                case TagToken.AlbumArtist:
                    tagAttribute = mp3.AlbumArtist;
                    break;
                case TagToken.BeatsPerMinute:
                    tagAttribute = mp3.BeatsPerMinute.ToString(CultureInfo.InvariantCulture);
                    break;
                case TagToken.Duration:
                    tagAttribute = mp3.Duration;
                    break;
                case TagToken.Title:
                    tagAttribute = mp3.Title;
                    break;
                case TagToken.Track:
                    tagAttribute = mp3.Track.ToString(CultureInfo.InvariantCulture);
                    break;
            }

            return GetNormalizedTagAttribute(tagAttribute);
        }

        public static int PercentOf(this int mp3Index, int mp3Count)
        {
            return (int)((double)mp3Index / mp3Count * 100);
        }

        private static string GetNormalizedTagAttribute(string rawAttribute)
        {
            return rawAttribute ?? string.Empty;
        }
    }
}
